package com.grace.cms.forum.user.service.tadlib;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.grace.redis.utils.RedisCache;
import com.alibaba.fastjson2.JSON;
import com.grace.cms.common.enums.RecordTypeEnums;
import com.grace.cms.common.model.support.PageData;
import com.grace.cms.forum.comment.domain.vo.CmsCommentVo;
import com.grace.cms.forum.user.service.cache.HandCommentCacheService;
import com.grace.common.config.GraceConfig;

/**
 * 评论标签服务
 * 提供评论相关的各种操作接口
 */
@Service("commentTag")
public class CommentTag {

    @Autowired
    private HandCommentCacheService webCommentCacheService;

    @Autowired
    private RedisCache redisCache;

    public PageData<CmsCommentVo> pageCommentRecent(String themeName, Integer pageNum, Integer pageSize) {
        return pageComment(null, null, null, null, themeName, pageNum, pageSize);
    }

    public PageData<CmsCommentVo> pageCommentRecordId(String recordId, RecordTypeEnums recordType, String themeName,
            Integer pageNum, Integer pageSize) {
        return pageComment(recordId, null, recordType, null, themeName, pageNum, pageSize);
    }

    public PageData<CmsCommentVo> pageCommentRecordType(RecordTypeEnums recordType, String themeName, Integer pageNum,
            Integer pageSize) {
        return pageComment(null, null, recordType, null, themeName, pageNum, pageSize);
    }

    public PageData<CmsCommentVo> pageCommentThemeName(Long orderNum, String themeName, Integer pageNum,
            Integer pageSize) {
        return pageComment(null, null, null, orderNum, themeName, pageNum, pageSize);
    }

    public PageData<CmsCommentVo> pageCommentFirstLeave(String recordId, RecordTypeEnums recordType, String themeName,
            Integer pageNum, Integer pageSize) {
        return pageComment(recordId, 0L, recordType, null, themeName, pageNum, pageSize);
    }

    public PageData<CmsCommentVo> pageCommentSecondLeave(Long parentId, RecordTypeEnums recordType, String themeName,
            Integer pageNum, Integer pageSize) {
        return pageComment(null, parentId, recordType, null, themeName, pageNum, pageSize);
    }

    public PageData<CmsCommentVo> pageCommentTree(String recordId, RecordTypeEnums recordType, String themeName,
            Integer pageNum, Integer pageSize) {
        PageData<CmsCommentVo> pageData = pageComment(recordId, null, recordType, null, themeName, pageNum, pageSize);
        List<CmsCommentVo> rows = pageData.getRows();
        if (rows != null && rows.size() > 0) {
            for (CmsCommentVo commentVo : rows) {
                commentVo.setChildPage(
                        pageCommentSecondLeave(commentVo.getCommentId(), recordType, themeName, 1, pageSize));
            }
        }
        return pageData;
    }

    /**
     * 综合条件查询评论列表
     * 
     * @param recordId   记录ID
     * @param parentId   父评论ID
     * @param recordType 记录类型
     * @param themeName  主题名称
     * @param onlyCode   站点编码
     * @param orderNum   排序号
     * @param pageNum    页码
     * @param pageSize   每页大小
     * @return 评论列表
     */
    public PageData<CmsCommentVo> pageComment(String recordId, Long parentId, RecordTypeEnums recordType, Long orderNum,
            String themeName, int pageNum, int pageSize) {
        // 获取评论ID列表
        PageData<Long> commentIdPageData = this.pageCommentIds(recordId, parentId, recordType, orderNum, themeName,
                pageNum, pageSize);

        // 将ID转换为字符串列表，用于批量查询缓存
        ArrayList<Object> commentIdObjects = new ArrayList<>(commentIdPageData.getRows().stream()
                .map(Object::toString)
                .collect(Collectors.toList()));

        // 批量获取缓存中的评论数据
        List<Object> rawList = redisCache.getMultiCacheMapValue(
                HandCommentCacheService.allKeyPrefix,
                commentIdObjects);

        // 将缓存数据转换为CmsCommentVo列表
        List<CmsCommentVo> listComment = rawList.stream()
                .map(obj -> JSON.parseObject(JSON.toJSONString(obj), CmsCommentVo.class))
                .collect(Collectors.toList());

        // 检查是否有缓存未命中的情况
        if (listComment.stream().anyMatch(comment -> comment == null)) {
            // 处理缓存未命中的情况，重新获取并更新缓存
            return new PageData<>(commentIdPageData.getTotal(), commentIdPageData.getCode(),
                    commentIdPageData.getPages(), commentIdPageData.getPageNum(), commentIdPageData.getPageSize(),
                    changeCommentVos(listComment, commentIdObjects, recordId, parentId, recordType, themeName, pageNum,
                            pageSize));
        } else {
            // 所有数据都命中缓存，直接返回
            return new PageData<>(commentIdPageData.getTotal(), commentIdPageData.getCode(),
                    commentIdPageData.getPages(), commentIdPageData.getPageNum(), commentIdPageData.getPageSize(),
                    listComment);
        }
    }

    /**
     * 处理缓存未命中的评论数据
     */
    private List<CmsCommentVo> changeCommentVos(List<CmsCommentVo> listComment, List<Object> commentIdObjects,
            String recordId, Long parentId, RecordTypeEnums recordType, String themeName, int pageNum, int pageSize) {
        // 创建一个新的列表用于保存非空的CmsCommentVo项
        List<CmsCommentVo> nonNullComments = new ArrayList<>();
        // 迭代listComment
        for (int i = 0; i < listComment.size(); i++) {
            CmsCommentVo comment = listComment.get(i);
            if (comment != null) {
                // 如果当前项不为null，则添加到新列表中
                nonNullComments.add(comment);
            } else {
                // 如果当前项为null，则从数据库获取
                Long commentId = Long.parseLong((String) commentIdObjects.get(i));
                CmsCommentVo dbComment = webCommentCacheService.selectCommentByIdAndTheme(commentId, themeName);
                if (dbComment != null) {
                    // 如果数据库中存在该评论，则添加到新列表中
                    nonNullComments.add(dbComment);
                } else {

                }
            }
        }
        return nonNullComments;
    }

    /**
     * 检查指定记录类型是否支持评论
     * 
     * @param recordType 记录类型
     * @return 是否支持评论
     */
    public boolean commentSupport(RecordTypeEnums recordType) {
        return webCommentCacheService.commentSupport(recordType);
    }

    /**
     * 检查指定记录类型和站点是否支持评论
     * 
     * @param recordType 记录类型
     * @param onlyCode   站点编码
     * @return 是否支持评论
     */
    public boolean commentSupport(RecordTypeEnums recordType, String onlyCode) {
        return webCommentCacheService.commentSupport(recordType, onlyCode);
    }

    /**
     * 获取评论ID列表
     */
    private PageData<Long> pageCommentIds(String recordId, Long parentId, RecordTypeEnums recordType, Long orderNum,
            String themeName, int pageNum, int pageSize) {
        return webCommentCacheService.pageCommentIds(recordId, parentId, recordType, orderNum, themeName,
                GraceConfig.getOnlyCode(), pageNum, pageSize);
    }
}
